/*
 * @(#)HelloAglet.java
 *
 * 03L7246 (c) Copyright IBM Corp. 1996, 1998
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package example.mdispatcher;

import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URL;

import com.ibm.aglet.Aglet;
import com.ibm.aglet.Message;
import com.ibm.aglet.util.AddressChooser;
import com.ibm.agletx.util.SimpleItinerary;

/**
 * <tt> HelloAglet </tt> is a revised version of examples.hello.HelloAglet,
 * which uses MethodDispatcher class to handle incoming messages.
 *
 * @version     1.00	$Date: 1999/10/27 05:16:39 $
 * @author	Danny B. Lange
 * @author	Mitsuru Oshima
 * @see examples.hello.HelloAglet
 * @see examples.examples.MethodDispatcher
 */
public class HelloAglet extends Aglet {

    /*
     * UI to interact with a User
     * this will be automatically disposed when the aglet is disposed
     */
    transient Frame my_dialog = null;

    /*
     * Default message
     */
    String message = "Hello World!";

    /*
     *
     */
    String home = null;

    /*
     * Itinerary
     */
    SimpleItinerary itinerary = null;

    /*
     * MethodDispatcher
     */
    MethodDispatcher mdispatcher = null;

    /*
     * Initializes the aglet. Only called the very first time this 
     * aglet is created. 
     */
    public void onCreation(Object init) {
	itinerary = new SimpleItinerary(this);
	mdispatcher = new MethodDispatcher(this);
	
	// Remember the URL as a string.
	home = getAgletContext().getHostingURL().toString();
    }

    /*
     * Go to the destination and say hello!
     */
    public void go(Message msg) {
		URL dest = (URL)msg.getArg();
		try {
	    	itinerary.go(dest.toString(), "sayHello");
		} catch (Exception ex) {
	    	ex.printStackTrace();
		}
    }

    /**
     * Dispatch the aglet to the destination.
     * @param destination a url which specifies the destination
     * @exception when the aglet is in the invalid state
     */
    public synchronized void goDestination(String destination) {
		try {
	    	itinerary.go(destination, "sayHello");
		} catch (Exception ex) {
	    	ex.printStackTrace();
		}
    }

    /*
     * Handles the message
     * @param msg the message sent
     */
    public boolean handleMessage(Message msg) {
		return mdispatcher.handleMessage(msg);
    }

    /*
     *
     */
    public void atHome(Message msg) {
		setText("I'm back.");
		waitMessage(2 * 1000);
		dispose();
    }

    /*
     * Say hello!
     */
    public void sayHello(Message msg) {
		// greetings
		setText(message);

		waitMessage(5 * 1000);

		try {
	    	setText("I'll go back to.. " + home);
	    	waitMessage(1000);
	    	itinerary.go(home, "atHome");
		} catch (Exception ex) {
	    	ex.printStackTrace();
		}
    }

    /**
     * Creates the dialog window. This has the reference to the instance
     * of the Dialog to avoid opening multiple dialog windows.
     */
    public void dialog(Message msg) {
		if (my_dialog == null) {
	    	my_dialog = new MyDialog(this);
	    	my_dialog.pack();
	    	my_dialog.setSize(my_dialog.getPreferredSize());
		}
		my_dialog.show();
    	}
}


/*
 * MyDialog class is the window to be opened when the dialog required.
 * This is NOT a subclass of Dialog.
 */
class MyDialog extends Frame implements ActionListener, WindowListener{
	
	/*
     * The aglet a user interacts with.
     */
    private HelloAglet aglet  = null;

    /*
     * UI Components
     */
    private AddressChooser dest = new AddressChooser();
    private TextField msg       = new TextField(15);
    private Button go           = new Button("GO!");
    private Button close        = new Button("CLOSE");
    
    /*
     * Constructs the dialog window
     * @param aglet The aglet the user interacts with.
     */
    MyDialog(HelloAglet aglet) {
		this.aglet = aglet;
		layoutComponents();
		
		addWindowListener(this);
		dest.addActionListener(this);
		msg.addActionListener(this);
		go.addActionListener(this);
		close.addActionListener(this);
    }

    /**
     * Handles the action event
     * @param ae the event to be handled
     */
	public void actionPerformed(ActionEvent ae){
		if("GO!".equals(ae.getActionCommand())){
			aglet.message = msg.getText();
	    	aglet.goDestination(dest.getAddress());
	    }else if("CLOSE".equals(ae.getActionCommand())){
			setVisible(false);
		}
	}
	
	/**
     * Handles the window event
     * @param ae the event to be handled
     */
	public void windowClosing(WindowEvent we){
		dispose();
	}
	
	public void windowOpened(WindowEvent we){
	}
	
	public void windowIconified(WindowEvent we){
	}
	
	public void windowDeiconified(WindowEvent we){
	}
	
	public void windowClosed(WindowEvent we){
	}
	
	public void windowActivated(WindowEvent we){
	}
	
	public void windowDeactivated(WindowEvent we){
	}


    
    /*
     * Layouts all components
     */
    private void layoutComponents() {
		msg.setText(aglet.message);

	// Layouts components
	GridBagLayout grid = new GridBagLayout();
	GridBagConstraints cns = new GridBagConstraints();
	setLayout(grid);

	cns.weightx = 0.5;
	cns.ipadx = cns.ipady = 5;
	cns.fill = GridBagConstraints.HORIZONTAL;
	cns.insets = new Insets(5,5,5,5);

	cns.weightx = 1.0;
	cns.gridwidth = GridBagConstraints.REMAINDER;
	grid.setConstraints(dest, cns);
	add(dest);

	cns.gridwidth = GridBagConstraints.REMAINDER;
	cns.fill = GridBagConstraints.BOTH;
	cns.weightx = 1.0;
	cns.weighty = 1.0;
	cns.gridheight = 2;
	grid.setConstraints(msg, cns);
	add(msg);

	cns.weighty = 0.0;
	cns.fill = GridBagConstraints.NONE;
	cns.gridheight = 1;

	Panel p = new Panel();

	grid.setConstraints(p, cns);
	add(p);
	p.setLayout(new FlowLayout());
	p.add(go);
	p.add(close);
    }
    
}

